package lasec.servlet;

import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import lasec.connect.DBManager;
import lasec.util.SCSVDRecommender;
import lasec.util.SSVDRecommender;

import org.apache.mahout.cf.taste.common.NoSuchUserException;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel;
import org.apache.mahout.cf.taste.impl.recommender.svd.SVDRecommender;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;

/**
 * Servlet implementation class RecommendServlet
 */
@WebServlet("/RecommendServlet")
public class RecommendServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private DataSource datasource = null;
	private DBManager manage = null;

	public void init() throws ServletException {
		super.init();
		Context context = null;
		manage = new DBManager();

		try {
			context = new InitialContext();
			datasource = (DataSource) context
					.lookup("java:/comp/env/jdbc/MySqlDS");
			context.close();
			context = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("init()" + this.getClass());
	}

	public void destroy() {
		System.out.println("Destroying..." + this.getClass());

		try {
			manage = null;
			datasource = null;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	protected void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		Long uid = Long.parseLong(request.getParameter("uid"));
		RequestDispatcher rd = null;
		MySQLJDBCDataModel model = new MySQLJDBCDataModel(
				(DataSource) datasource, "user_movie_rate", "user_id",
				"movie_id", "movie_rate", "");

		Recommender svdrecommender = null;
		Recommender ssvdrecommender = null;
		Recommender scsvdrecommender = null;

		List<RecommendedItem> svdrecommendations = null;
		List<RecommendedItem> ssvdrecommendations = null;
		List<RecommendedItem> scsvdrecommendations = null;

		HashMap<Integer, String> svdmovie = null;
		HashMap<Integer, String> ssvdmovie = null;
		HashMap<Integer, String> scsvdmovie = null;

		System.out.println("Recommending to user: " + uid);
		
		try {
			svdrecommender = new lasec.util.SVDRecommender(model, uid);
			ssvdrecommender = new SSVDRecommender(model, uid, 0.5);
			scsvdrecommender = new SCSVDRecommender(model, uid, 0.5);

		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			svdrecommendations = svdrecommender.recommend(uid, 10);
			ssvdrecommendations = ssvdrecommender.recommend(uid, 10);
			scsvdrecommendations = scsvdrecommender.recommend(uid, 10);

			Vector<Integer> movieIDs = new Vector<Integer>();

			manage.deleteMovieSurvey(uid);
			
			if (svdrecommendations.size() >= 1) {
				for (RecommendedItem recommendation : svdrecommendations) {
					movieIDs.add((int) recommendation.getItemID());
				}
			}

			manage.insertMovieSurvey(uid, 0, movieIDs);

			svdmovie = manage.searchMovie(movieIDs);

			movieIDs.clear();

			if (ssvdrecommendations.size() >= 1) {
				for (RecommendedItem recommendation : ssvdrecommendations) {
					movieIDs.add((int) recommendation.getItemID());
				}
			}

			manage.insertMovieSurvey(uid, 1, movieIDs);

			ssvdmovie = manage.searchMovie(movieIDs);

			movieIDs.clear();

			if (scsvdrecommendations.size() >= 1) {
				for (RecommendedItem recommendation : scsvdrecommendations) {
					movieIDs.add((int) recommendation.getItemID());
				}
			}
			
			manage.insertMovieSurvey(uid, 2, movieIDs);
			
			scsvdmovie = manage.searchMovie(movieIDs);
			
			request.setAttribute("svdmovie", svdmovie);
			request.setAttribute("ssvdmovie", ssvdmovie);
			request.setAttribute("scsvdmovie", scsvdmovie);
			
			svdrecommender = null;
			ssvdrecommender = null;
			scsvdrecommender = null;

			svdrecommendations = null;
			ssvdrecommendations = null;
			scsvdrecommendations = null;
			
			rd = getServletContext().getRequestDispatcher("/JSP/recommendation.jsp");
			rd.forward(request, response);
		} catch (Exception e) {
			e.printStackTrace();
			svdrecommender = null;
			ssvdrecommender = null;
			scsvdrecommender = null;
			svdrecommendations = null;
			ssvdrecommendations = null;
			scsvdrecommendations = null;
			rd = getServletContext().getRequestDispatcher("/JSP/recommendation.jsp");
			rd.forward(request, response);
		}
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

}